/*!
 * \file MQClient.h
 * \project	WonderTrader
 *
 * \author Wesley
 * \date 2020/03/30
 *
 * \brief 消息队列客户端头文件
 * 
 * \details 本文件定义了WonderTrader消息队列系统的客户端类：
 *          - 基于UDP协议实现消息接收客户端
 *          - 支持多主题消息订阅功能
 *          - 提供异步消息接收机制
 *          - 实现消息过滤和主题匹配
 *          - 支持消息回调处理机制
 *          - 提供高性能的消息接收能力
 */
#pragma once
#include "PorterDefs.h"
#include <queue>

#include "../Includes/WTSMarcos.h"
#include "../Includes/FasterDefs.h"
#include "../Share/StdUtils.hpp"

NS_WTP_BEGIN
class MQManager;

/**
 * @brief 消息队列客户端类
 * @details 实现基于UDP的消息接收客户端，支持主题订阅和异步消息处理
 */
class MQClient
{
public:
	/**
	 * @brief 构造函数
	 * @details 初始化消息客户端实例
	 * @param mgr 消息队列管理器指针
	 */
	MQClient(MQManager* mgr);
	
	/**
	 * @brief 析构函数
	 * @details 清理客户端资源，关闭网络连接和线程
	 */
	~MQClient();

private:
	/**
	 * @brief 提取缓冲区数据
	 * @details 从接收缓冲区中提取完整的消息包并处理
	 */
	void	extract_buffer();

	/**
	 * @brief 检查主题是否允许
	 * @details 检查指定主题是否在订阅列表中
	 * @param topic 要检查的主题名称
	 * @return bool 是否允许该主题的消息
	 */
	inline bool	is_allowed(const char* topic)
	{
		// 如果没有订阅任何主题，则允许所有消息
		if (_topics.empty())
			return true;

		// 检查主题是否在订阅列表中
		auto it = _topics.find(topic);
		if (it != _topics.end())
			return true;

		return false;
	}

public:
	/**
	 * @brief 获取客户端ID
	 * @details 返回客户端的唯一标识ID
	 * @return uint32_t 客户端ID
	 */
	inline uint32_t id() const { return _id; }

	/**
	 * @brief 初始化客户端
	 * @details 根据URL初始化UDP客户端，创建套接字并设置回调
	 * @param url 服务器URL地址（格式：udp://ip:port）
	 * @param cb 消息接收回调函数
	 * @return bool 初始化是否成功
	 */
	bool	init(const char* url, FuncMQCallback cb);

	/**
	 * @brief 启动客户端
	 * @details 启动消息接收线程，开始监听消息
	 */
	void	start();

	/**
	 * @brief 订阅主题
	 * @details 添加要订阅的消息主题
	 * @param topic 要订阅的主题名称
	 */
	inline void	sub_topic(const char* topic)
	{
		_topics.insert(topic);
	}

private:
	std::string		m_strURL;		/*!< 服务器URL地址 */
	bool			m_bReady;		/*!< 客户端就绪状态 */
	int				_sock;			/*!< UDP套接字句柄 */
	MQManager*		_mgr;			/*!< 消息队列管理器指针 */
	uint32_t		_id;			/*!< 客户端唯一ID */

	StdThreadPtr	m_thrdRecv;		/*!< 消息接收线程 */
	bool			m_bTerminated;	/*!< 线程终止标志 */

	std::string		_buffer;		/*!< 消息接收缓冲区 */
	FuncMQCallback	_cb_message;	/*!< 消息回调函数指针 */

	faster_hashset<std::string> _topics;	/*!< 订阅主题集合 */
	char			_recv_buf[1024 * 1024];	/*!< 接收缓冲区，1MB大小 */
};

NS_WTP_END